<script setup>
import { ref, reactive, onMounted, onUnmounted } from "vue";
import { useRouter, useRoute } from "vue-router";
import { useCounterStore } from "@/stores/counter";
import axios from "axios";
import { detectFace } from "@/api/api";
const counterStore = useCounterStore();
const router = useRouter();
const route = useRoute();
const modeType = ref(0);
const step = ref(0);
const video = ref(null);
const canvas = ref(null);
const countdown = ref(0);
const captured = ref(false);
const videoLoaded = ref(false);
const imageData = ref("");
const croppedimage = ref("");
const videoDevices = ref([]);
const selectedCameraId = ref("");
const imageLoading = ref(true);
// 错误信息
const errorMessage = ref("");

const startCamera = async () => {
  try {
    videoLoaded.value = false; // Reset video loaded state
    if (video.value && video.value.srcObject) {
      const tracks = video.value.srcObject.getTracks();
      tracks.forEach((track) => track.stop());
    }

    const stream = await navigator.mediaDevices.getUserMedia({
      video: {
        deviceId: selectedCameraId.value
          ? { exact: selectedCameraId.value }
          : undefined,
        width: { ideal: 1920 },
        height: { ideal: 1080 },
      },
    });
    if (video.value) {
      video.value.srcObject = stream;
      video.value.play();
    }
  } catch (err) {
    console.error("Error accessing camera: ", err);
  }
};

const onVideoLoaded = () => {
  videoLoaded.value = true;
  if (video.value) {
    video.value.style.transform = "translate(-50%, 0) rotate(0deg)";
  }
};

const getCameras = async () => {
  try {
    await navigator.mediaDevices.getUserMedia({ video: true });
    const devices = await navigator.mediaDevices.enumerateDevices();

    videoDevices.value = devices;
    //videoDevices.value = devices.filter(device => device.kind === 'videoinput');

    const backCamera = videoDevices.value.find(
      (device) =>
        device.label.toLowerCase().includes("back") ||
        device.label.toLowerCase().includes("rear") ||
        device.label.toLowerCase().includes("环境") ||
        device.label.toLowerCase().includes("后置")
    );

    console.log(videoDevices.value, "videoDevices.value");

    if (backCamera) {
      selectedCameraId.value = backCamera.deviceId;
      console.log("使用后置摄像头:", backCamera.label);
    } else if (videoDevices.value.length > 0) {
      selectedCameraId.value = videoDevices.value[1].deviceId;
      console.log("使用默认摄像头:", videoDevices.value[1].label);
    }
  } catch (err) {
    console.error("Error accessing camera: ", err);
  }
};

const startCountdown = () => {
  step.value = 1;
  setTimeout(() => {
    captureImage();
  }, 1000);
};

const captureImage = () => {
  countdown.value = 3;
  const interval = setInterval(() => {
    countdown.value--;
    if (countdown.value === 0) {
      clearInterval(interval);
      takePhoto();
    }
  }, 1000);
};

const closeCamera = () => {
  if (video.value && video.value.srcObject) {
    const tracks = video.value.srcObject.getTracks();
    tracks.forEach((track) => track.stop());
    video.value.srcObject = null;
  }
};

const takePhoto = () => {
  const context = canvas.value.getContext("2d");
  canvas.value.width = 1080;
  canvas.value.height = 1920;
  context.save();
  context.translate(1080 / 2, 1920 / 2);
  context.rotate(0);
  context.drawImage(video.value, -1080 / 2, -1920 / 2, 1080, 1920);
  context.restore();

  imageData.value = canvas.value.toDataURL("image/png");
  step.value = 2;

  detectFace({ image: imageData.value, modeType: modeType.value })
    .then((response) => {
      console.log(response, "response");
      let { cropped_image, has_face } = response.data;
      croppedimage.value = cropped_image;
      localStorage.setItem("croppedimage", croppedimage.value);
      imageLoading.value = false;
      // 接口调用成功后关闭摄像头
      closeCamera();
    })
    .catch((error) => {
      errorMessage.value = error.error;
      console.error(errorMessage.value, "Error:", error);
      setTimeout(() => {
        retakePhoto();
        imageLoading.value = false;
      }, 3000);
    });
};

const retakePhoto = () => {
  captured.value = false;
  imageLoading.value = true;
  step.value = 0;
  imageData.value = "";
  croppedimage.value = "";
  // 重新开始摄像头
  startCamera();
};

onMounted(async () => {
  // 获取url参数
  modeType.value = route.query.type;
  localStorage.setItem("modeType", modeType.value);
  await getCameras();
  await startCamera();
});

onUnmounted(() => {
  if (video.value && video.value.srcObject) {
    const tracks = video.value.srcObject.getTracks();
    tracks.forEach((track) => track.stop());
  }
});

const getClass = (index) => {
  return {
    bigActive: index === countdown.value,
  };
};
</script>

<template>
  <div class="camera-container">
    <Dialog v-if="errorMessage" :message="errorMessage"></Dialog>
    <!-- <img
      :src="imageData"
      alt=""
      style="
        position: absolute;
        top: 0;
        left: 0;
        width: 540px;
        height: 960px;
        z-index: 100;
      "
    /> -->
    <div v-show="step === 0" class="section">
      <img
        class="camera-bg"
        src="@/assets/images/small/camera/camera-bg.png"
        alt=""
      />
      <img class="title" src="@/assets/images/small/camera/title.png" />
      <img class="tipsbox" src="@/assets/images/small/camera/line.png" />
      <div class="overlay"></div>
      <stcBotton class="btnstart" title="Ready!" @click="startCountdown" />
    </div>
    <div v-show="step === 1" class="section">
      <video
        ref="video"
        autoplay
        playsinline
        @loadeddata="onVideoLoaded"
        class="camera-video"
      ></video>
      <img class="tipsbox" src="@/assets/images/small/camera/line.png" />
      <canvas ref="canvas" class="camera-canvas"></canvas>
      <div class="overlay">
        <div class="countdown" v-if="countdown > 0">
          <span :class="getClass(3)">3,</span>
          <span :class="getClass(2)">2,</span>
          <span :class="getClass(1)">1</span>
        </div>
      </div>
    </div>
    <div v-show="step === 2" class="section">
      <div v-if="imageLoading" class="loading-spinner"></div>
      <template v-if="!imageLoading">
        <img
          class="title title2"
          src="@/assets/images/small/camera/title2.png"
        />
        <img :src="croppedimage" alt="Captured Image" class="captured-image" />
        <stcBotton class="retake" title="Retake" @click="retakePhoto" />
        <stcBotton
          class="continue"
          title="Continue"
          targetRoute="/small/location"
        />
        <!-- <clickable-button
          class="btn proceed"
          :imageSrc="proceed"
          targetRoute="/generate"
        /> -->
        <!-- <clickable-button
          class="btn retake"
          :imageSrc="retake"
          @click="retakePhoto"
        /> -->
      </template>
    </div>
  </div>
</template>

<style scoped lang="scss">
.camera-container,
.section {
  width: 100%;
  height: 100%;
  position: absolute;
  top: 0;
  left: 0;
}
.camera-bg {
  width: 100%;
  position: absolute;
  top: -15%;
  left: 0;
}
.title {
  width: 795px;
  position: absolute;
  top: 5%;
  left: 50%;
  transform: translate(-50%, 0);
}
.title2 {
  width: 584px;
  position: absolute;
  top: 5%;
  left: 50%;
  transform: translate(-50%, 0);
}
.tipsbox {
  width: 660px;
  height: 660px;
  position: absolute;
  top: 20%;
  left: 50%;
  transform: translate(-50%, 0);
}

.ready {
  width: 467px;
  bottom: 378px;
}

.camera-video {
  width: 100%;
  height: 100%;
  position: absolute;
  left: 50%;
  object-fit: cover;
  // transform-origin: center;
}

.camera-canvas {
  display: none;
}

.overlay {
  position: absolute;
  bottom: 0;
  left: 0;
  width: 100%;
  height: 500px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: linear-gradient(180deg, rgba(79, 0, 140, 0) 0%, #4f008c 100%);
}

.countdown {
  font-weight: bold;
  font-family: "stc-exbold";
  color: #fff;
  font-size: 100px;
  display: flex;
  justify-content: center;
  line-height: 160px;
  span {
    margin: 0 15px;
    transition: all 0.2s linear;
  }
  .bigActive {
    font-size: 160px;
  }
}

.scanicon {
  width: 600px;
  top: 473px;
}

button {
  font-size: 1.5em;
  padding: 0.5em 1em;
  margin-top: 1em;
}

.result-container {
  width: 1080px;
  height: 1920px;
  position: absolute;
  top: 0;
  left: 0;
}

.captured-image {
  width: 660px;
  height: 660px;
  position: absolute;
  left: 50%;
  top:20%;
  transform: translate(-50%, 0);
}

.proceed {
  bottom: 466px;
}
.btnstart {
  left: 50%;
  top: 76%;
  transform: translate(-50%, 0);
}
.retake {
  left: 50%;
  top:75%;
  transform: translate(-50%, 0);
}

.continue {
  left: 50%;
  top: 86%;
  transform: translate(-50%, 0);
}

.actions {
  display: flex;
  gap: 1em;
}

.btn-ready {
  bottom: 384px;
}

.camera-selection {
  width: 300px;
  height: 150px;
  position: absolute;
  top: 50px;
  left: 50px;
  opacity: 0;
}

.loading-spinner {
  border: 8px solid rgba(255, 255, 255, 0.3);
  border-radius: 50%;
  border-top: 8px solid #fff;
  width: 60px;
  height: 60px;
  animation: spin 1s linear infinite;
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  z-index: 10;
}

@keyframes spin {
  0% {
    transform: translate(-50%, -50%) rotate(0deg);
  }

  100% {
    transform: translate(-50%, -50%) rotate(360deg);
  }
}
</style>
